<template>
	<view
		v-if="visibleSync"
		:class="{ 'uni-drawer': true, 'uni-drawer__visible': showDrawer, 'uni-drawer__right': rightMode, 'uni-drawer__bottom': bottomMode }"
		@touchmove.stop.prevent="() => {}"
	>
		<view class="uni-drawer__mask" @tap="__maskClose(maskClose)" />
		<view class="uni-drawer__content" :style="{ width: width, height: height, top: top, bottom: 0 }">
			<view class="uni-drawer__body"><slot /></view>
		</view>
	</view>
</template>

<script>
export default {
	name: 'UniDrawer',
	props: {
		visible: {
			type: Boolean,
			default: false
		},
		mode: {
			type: String,
			default: 'right'
		},
		mask: {
			type: Boolean,
			default: true
		},
		maskClose: {
			type: Boolean,
			default: true
		},
		size: {
			type: String,
			default: '100%'
		},
		title: {
			type: String,
			default: ''
		}
	},
	data() {
		return {
			visibleSync: false,
			showDrawer: false,
			rightMode: false,
			bottomMode: false,
			closeTimer: null,
			watchTimer: null,
			showClose: false,
			width: '100%',
			height: '100%',
			top: 0
		};
	},
	watch: {
		visible(val) {
			clearTimeout(this.watchTimer);
			setTimeout(() => {
				this.showDrawer = val;
			}, 100);
			if (this.visibleSync) {
				clearTimeout(this.closeTimer);
			}
			if (val) {
				this.visibleSync = val;
			} else {
				this.watchTimer = setTimeout(() => {
					this.visibleSync = val;
				}, 300);
			}
		}
	},
	methods: {
		show() {
			this.visibleSync = true;
			if (this.mode === 'right') {
				this.rightMode = true;
				if (this.size === '100%') {
					this.showClose = true;
				}
				this.width = this.size;
			} else if (this.mode === 'bottom') {
				this.bottomMode = true;
				this.width = '100%';
				this.height = this.size;
				this.top = 'unset';
			}
			setTimeout(() => {
				this.showDrawer = true;
			}, 10);
		},
		__maskClose(flag) {
			if (!flag) {
				return;
			}
			this.close();
		},
		close() {
			this.showDrawer = false;
			this.$emit('update:visible', false);
			this.$emit('close');
			this.closeTimer = setTimeout(() => {
				this.visibleSync = false;
			}, 300);
		}
	}
};
</script>

<style lang="less">
.uni-drawer {
	display: block;
	position: fixed;
	/* #ifdef H5*/
	top: 44px;
	/* #endif */
	/* #ifdef APP-PLUS || MP-WEIXIN */
	top: 0;
	/* #endif */
	left: 0;
	right: 0;
	bottom: 0;
	overflow: hidden;
	visibility: hidden;
	z-index: 999;

	&.uni-drawer__right {
		.uni-drawer__content {
			left: unset;
			right: 0;
			transform: translate(100%, 0);
		}
	}
	&.uni-drawer__bottom {
		.uni-drawer__content {
			left: 0;
			right: 0;
			transform: translate(0, 100%);
		}
	}

	&.uni-drawer__visible {
		visibility: visible;

		.uni-drawer__content {
			transform: translate(0, 0);
		}

		.uni-drawer__mask {
			display: block;
			opacity: 1;
		}
	}

	.uni-drawer__mask {
		display: block;
		opacity: 0;
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background: rgba(0, 0, 0, 0.4);
		transition: opacity 0.3s;
	}
	.uni-drawer__body {
		height: calc(100% - 88upx);
	}
	.uni-drawer__content {
		display: block;
		position: absolute;
		top: 0;
		left: 0;
		height: 100%;
		background: #fff;
		transition: all 0.3s ease-out;
		transform: translate(-100%, 0);
	}
}
</style>
